//
// Created by hkkzzxz on 24-9-1.
//

#ifndef YUNSHI_MYSQLDATABASEMODEL_H
#define YUNSHI_MYSQLDATABASEMODEL_H

// MySQL数据库CURD

#include <mysql/jdbc.h>

#include "LogManager.h"
#include "MySQLConnectionPool.h"

class MySQLDatabaseModel {
public:
    // 判断是否有查询结果
    bool queryBool(std::string &query, const std::vector<std::string> &params);

    // 插入数据
    bool insert(std::string &insert, const std::vector<std::string> &params);

    // 更新数据
    bool update(std::string &update, const std::vector<std::string> &params);

    // 实体查询
    template<typename T>
    std::vector<std::unique_ptr<T>> queryModel(std::string &query, const std::vector<std::string> &params) {
        std::vector<std::unique_ptr<T>> models;

        MySQLConnectionPool *pool = MySQLConnectionPool::getInstance();
        auto mysqlConn = pool->getConnection();
        if (!mysqlConn) {
            pool->releaseConnection(mysqlConn);
            consoleLogger->error("get MySQL connection failed");
            fileLogger->error("get MySQL connection failed");
            return models;
        }

        consoleLogger->info("get MySQL connection successful");
        try {
            std::unique_ptr<sql::PreparedStatement> prepStmt(mysqlConn->prepareStatement(query));
            for (size_t i = 0; i < params.size(); ++i) {
                prepStmt->setString(i + 1, params[i]);
            }
            std::unique_ptr<sql::ResultSet> res(prepStmt->executeQuery());
            while (res->next()) {
                auto model = std::make_unique<T>();
                model->FillFromRow(res.get());
                models.push_back(std::move(model));
            }
            consoleLogger->info("query failed");
        }
        catch (std::exception const &e) {
            consoleLogger->error("MySQL error: " + std::string(e.what()));
            fileLogger->error("MySQL error: " + std::string(e.what()));
        }
        pool->releaseConnection(mysqlConn);
        return models;
    }

private:
    LogManager *logManager = LogManager::getInstance();
    std::shared_ptr<spdlog::logger> consoleLogger = logManager->getConsoleLogger();
    std::shared_ptr<spdlog::logger> fileLogger = logManager->getFileLogger();
};


#endif //YUNSHI_MYSQLDATABASEMODEL_H
